package main

import (
	"encoding/json"
	"io"
	"net/http"
)

func main() {
	http.HandleFunc("/hello", Hello)
	// http.HandleFunc("/SignUp", SignUp)
	s := NewSignServer("web1")
	s.Route("/SignUp", SignUp)
	s.Start(":8089")
}

func Hello(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("hello Go Web"))
}

type signUpReq struct {
	Email             string `json:"email"`
	Password          string `json:"password"`
	ConfirmedPassword string `json:"con"`
}

// -----------------------------增加Server-------------------------------
type Server interface {
	// Route 设定路由
	// Route(pattern string, hendlerFunc http.HandlerFunc)
	Route(pattern string, hendlerFunc func(c *Context))
	// strat 启动服务器的指令
	Start(address string) error
}

type HttpServer struct {
	// Name 标识字段
	Name string

	// 拓展别的字段······
}

// 路由
func (s *HttpServer) Route(pattern string, handlerfunc func(c *Context)) {
	// http.HandleFunc(pattern, handlerfunc)
	http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) { //这里的参数应该怎么传参？
		c := NewContext(w, r)
		handlerfunc(c) // 这里是一个函数转化
	})
}

// 监听
func (s *HttpServer) Start(address string) error {
	return http.ListenAndServe(address, nil)
}

// 构造
func NewSignServer(name string) Server {
	return &HttpServer{
		Name: name,
	}
}

// ---------------------------------------------------------------------

// -----------------------------增加Context-------------------------------

type Context struct {
	W http.ResponseWriter
	R *http.Request
}

// 封装出来之后，就需要有一个构造方法
func NewContext(w http.ResponseWriter, r *http.Request) *Context {
	return &Context{
		W: w,
		R: r,
	}
}

// 返回对象
type commonResponse struct {
	BizCode int         `json:"biz_code"`
	Msg     string      `json:"msg"`
	Data    interface{} `json:"data"`
}

// 从json中读取信息
func (c *Context) ReadJson(data interface{}) error {
	body, err := io.ReadAll(c.R.Body)
	if nil != err {
		return err
	}
	return json.Unmarshal(body, data)
}

// 返回json
func (c *Context) WriteJson(states int, data interface{}) error {
	bs, err := json.Marshal(data)
	if err != nil {
		return err
	}
	_, err = c.W.Write(bs)
	if nil != err {
		return err
	}
	c.W.WriteHeader(states)
	return nil
}

func (c *Context) OkJson(data interface{}) error {
	return c.WriteJson(http.StatusOK, data)
}

func (c *Context) SystemErrJson(data interface{}) error {
	return c.WriteJson(http.StatusInternalServerError, data)
}

func (c *Context) BadRequestJson(data interface{}) error {
	return c.WriteJson(http.StatusBadRequest, data)
}

// ---------------------------------------------------------------------

// 这个实现不连贯（w,r）
// func SignUp(w http.ResponseWriter, r *http.Request) {
// 	c := NewContext(w, r)
// 	req := signUpReq{}
// 	err := c.ReadJson(req)
// 	if nil != err {
// 		_ = c.BadRequestJson(&commonResponse{
// 			BizCode: 4,
// 			Msg:     "invaild request",
// 		})
// 		return
// 	}
// 	_ = c.OkJson(&commonResponse{
// 		Data: 1234,
// 	})
// }
func SignUp(c *Context) {
	req := signUpReq{}
	err := c.ReadJson(req)
	if nil != err {
		_ = c.BadRequestJson(&commonResponse{
			BizCode: 4,
			Msg:     "invaild request",
		})
		return
	}
	_ = c.OkJson(&commonResponse{
		Data: 1234,
	})
}
